package com.kaikeba.estack.service;


import com.google.common.collect.ImmutableMap;
import com.kaikeba.estack.bean.User;
import com.kaikeba.estack.common.RoleEnum;
import com.kaikeba.estack.common.util.StringUtils;
import com.kaikeba.estack.dao.UserDao;
import com.kaikeba.estack.dao.imp.UserDaoMysql;
import com.kaikeba.estack.web.dto.PageDto;
import com.kaikeba.estack.web.dto.SortDto;

import java.util.*;

import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE;

public class UserService {

    private static UserDao dao = new UserDaoMysql();

    /**
     * 更新登陆时间与ip
     *
     * @param username
     * @param date
     * @param ip
     */
    public static void updateLoginTimeAndIP(String username, Date date, String ip) {
        dao.updateLoginTime(username, date, ip);
    }

    /**
     * 登陆
     *
     * @param username
     * @param password
     * @return true表示成功，false表示登陆失败
     */
    public static List<User> queryUserByUsernamePassword(String username, String password) {
        return dao.queryUserByUsernamePassword(username, password);
    }

    /**
     * 根据条件查询1个用户
     *
     * @param key
     * @param value
     * @return
     */
    public static User queryExists(String key, String value) {
        List<User> list = dao.list("select * from e_user where `" + LOWER_CAMEL.to(LOWER_UNDERSCORE, key) + "` = :" + key + " limit 1",
                ImmutableMap.of(key, value));
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }


    /**
     * 分页查询
     *
     * @param pageDto
     * @return
     */
    public static PageDto<User> queryCourierByPage(PageDto pageDto) {
        //查询sql
        StringBuilder listSql = new StringBuilder("select *,(SELECT GROUP_CONCAT(role) FROM e_user_role r WHERE r.user_id = u.id) roles from e_user u ");
        StringBuilder countSql = new StringBuilder("select count(*) from e_user u ");


        //最终的sql参数
        Map<String, Object> searchWhere = new HashMap<>();
        StringBuilder whereSql = new StringBuilder();

        //构建查询的sql 同时也设置sql的条件参数
        whereSql = buildSearchSql(pageDto, searchWhere, whereSql);

        //查询总数
        long count = dao.count(countSql.append(whereSql)
                .toString(), searchWhere);
        pageDto.setCount(count);

        //构建排序的sql
        buildOrderSql(pageDto, whereSql);

        //构建分页的sql
        buildPageSql(pageDto, whereSql, searchWhere);

        List<User> userList = dao.list(listSql.append(whereSql)
                .toString(), searchWhere);

        pageDto.setItems(userList);
        return pageDto;
    }

    /**
     * 构建查询的sql
     *
     * @param pageDto
     * @param searchWhere
     * @param whereSql
     * @return
     */
    private static StringBuilder buildSearchSql(PageDto pageDto, Map<String, Object> searchWhere, StringBuilder whereSql) {
        Map<String, Object> search = pageDto.getSearch();
        if (search != null && search.size() > 0) {
            boolean match = search.values()
                    .stream()
                    .anyMatch(value -> {
                        if (value instanceof String) {
                            return !StringUtils.isEmpty(value);
                        } else {
                            return value != null;
                        }
                    });
            if (match) {
                whereSql.append(" where ");
                StringBuilder finalWhereSql = whereSql;
                search.forEach((key, value) -> {
                    finalWhereSql.append(" u.")
                            .append(LOWER_CAMEL.to(LOWER_UNDERSCORE, key))
                            .append(" like ")
                            .append(":")
                            .append(key)
                            .append(" and ");

                    searchWhere.put(key, "%" + value + "%");
                });
                //将最后一个条件多出来的and去除
                whereSql = new StringBuilder(whereSql.substring(0, whereSql.length() - 5));
            }
        }
        if (searchWhere.isEmpty()) {
            whereSql.append(" where exists(select 1 from e_user_role r where r.user_id = u.id and r.role = :role) ");
        } else {
            whereSql.append(" and exists(select 1 from e_user_role r where r.user_id = u.id and r.role = :role) ");
        }
        searchWhere.put("role", RoleEnum.COURIER.getEnName());
        return whereSql;
    }

    /**
     * 构建分页的sql
     *
     * @param pageDto
     * @param whereSql
     * @param searchWhere
     */
    private static void buildPageSql(PageDto pageDto, StringBuilder whereSql, Map<String, Object> searchWhere) {
        whereSql.append(" limit :pageStart,:limit");
        long pageCount = pageDto.getCount() / pageDto.getLimit();
        long page = Long.min(Integer.max(pageDto.getPage(), 1), pageDto.getCount() % pageDto.getLimit() == 0 ? pageCount : (pageCount + 1));
        long pageStart = (page - 1) * pageDto.getLimit();
        searchWhere.put("pageStart", pageStart);
        searchWhere.put("limit", pageDto.getLimit());
    }

    /**
     * 构建排序sql
     *
     * @param pageDto
     * @param whereSql
     */
    private static void buildOrderSql(PageDto pageDto, StringBuilder whereSql) {
        SortDto sort = pageDto.getSort();
        if (sort != null && sort.getFieldName() != null && sort.getOrder() != null) {
            whereSql.append(" order by u.")
                    .append(LOWER_CAMEL.to(LOWER_UNDERSCORE, sort.getFieldName()))
                    .append(" ")
                    .append(sort.getOrder());
        }
    }
}
